#include "image.h"
#include "../glvars.h"
int ImageLoad(char *filename, Image *image) {
	FILE *file;
	unsigned long size; // size of the image in bytes.
	unsigned long i; // standard counter.
	unsigned short int planes; // number of planes in image (must be 1)
	unsigned short int bpp; // number of bits per pixel (must be 24)
	char temp; // temporary color storage for bgr-rgb conversion.

	// make sure the file is there.
	if ((file = fopen(filename, "rb")) == NULL) {
		printf("File Not Found : %s\n", filename);
		return 0;
	}

	// seek through the bmp header, up to the width/height:
	fseek(file, 18, SEEK_CUR);

	// read the width
	if ((i = fread(&image->sizeX, 4, 1, file)) != 1) {
		printf("Error reading width from %s.\n", filename);
		return 0;
	}
	printf("Width of %s: %lu\n", filename, image->sizeX);

	// read the height
	if ((i = fread(&image->sizeY, 4, 1, file)) != 1) {
		printf("Error reading height from %s.\n", filename);
		return 0;
	}
	printf("Height of %s: %lu\n", filename, image->sizeY);

	// calculate the size (assuming 24 bits or 3 bytes per pixel).
	size = image->sizeX * image->sizeY * 3;

	// read the planes
	if ((fread(&planes, 2, 1, file)) != 1) {
		printf("Error reading planes from %s.\n", filename);
		return 0;
	}
	if (planes != 1) {
		printf("Planes from %s is not 1: %u\n", filename, planes);
		return 0;
	}

	// read the bpp
	if ((i = fread(&bpp, 2, 1, file)) != 1) {
		printf("Error reading bpp from %s.\n", filename);
		return 0;
	}
	if (bpp != 24) {
		printf("Bpp from %s is not 24: %u\n", filename, bpp);
		return 0;
	}

	// seek past the rest of the bitmap header.
	fseek(file, 24, SEEK_CUR);

	// read the data.
	image->data = (char *) malloc(size);
	if (image->data == NULL) {
		printf("Error allocating memory for color-corrected image data");
		return 0;
	}

	if ((i = fread(image->data, size, 1, file)) != 1) {
		printf("Error reading image data from %s.\n", filename);
		return 0;
	}

	for (i = 0; i < size; i += 3) { // reverse all of the colors. (bgr -> rgb)
		temp = image->data[i];
		image->data[i] = image->data[i + 2];
		image->data[i + 2] = temp;
	}

	// we're done.
	return 1;
}

// Load Bitmaps And Convert To Textures
void LoadGLTextures() {
	// Load Texture
	Image *image1;

	// allocate space for texture
	image1 = (Image *) malloc(sizeof(Image));
	if (image1 == NULL) {
		printf("Error allocating space for image");
		exit(0);
	}

	if (!ImageLoad("Tex/textur.bmp", image1)) {
		exit(1);
	}

	// Create Texture
	glGenTextures(1, &texture[0]);
	glBindTexture(GL_TEXTURE_2D, texture[0]); // 2d texture (x and y size)
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // scale linearly when image bigger than texture
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // scale linearly when image smalled than texture

	// 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image,
	// border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.
	glTexImage2D(GL_TEXTURE_2D, 0, 3, image1->sizeX, image1->sizeY, 0, GL_RGB,
			GL_UNSIGNED_BYTE, image1->data);
}

void init(void) {
	LoadGLTextures(); // Load The Texture(s)
	//glEnable(GL_TEXTURE_2D);			// Enable Texture Mapping
	//glClearColor(0.0, 0.0, 0.0, 0.0);
	glClearColor (1.0, 1.0, 1.0, 1.0);
	//glShadeModel (GL_FLAT);
	glShadeModel(GL_SMOOTH); /* Flaechen sollen runden Eindruck machen */
	nippel = gluNewQuadric(); /* Eine Datenstruktur fuer eine Quadrik
	 wird initialisiert */
	gluQuadricDrawStyle(nippel, GLU_FILL); /* Diese Quadrik soll
	 flaechig dargestellt werden */
	gluQuadricNormals(nippel, GLU_SMOOTH); /* Fuer jede Ecke soll eine
	 Normale berechnet werden */
	zyl1 = gluNewQuadric();
	gluQuadricDrawStyle(zyl1, GLU_FILL);
	gluQuadricNormals(zyl1, GLU_SMOOTH);

	kugel = gluNewQuadric();
	gluQuadricDrawStyle(kugel, GLU_FILL);
	gluQuadricNormals(kugel, GLU_SMOOTH);

	glMatrixMode(GL_MODELVIEW);
	//gluSphere(zyl,2,50,50); // kugel zeichnen     Obj,radius, slices, stacks

}


void beleuchte(void) /* Beleuchtungsmodell */
{
	GLfloat ambient[] = { 0.25, 0.20725, 0.20725, 1.0 };
	//GLfloat ambient[] = { 1.0, 1.0, 1.0, 1.0 };
	GLfloat diffus[] = { 1.0, 0.829, 0.829, 1.0 };
	//GLfloat diffus[]  = { 0.7, 0.7, 0.7, 1.0 };
	//GLfloat spiegel[] = { 0.296648, 0.296648, 0.296648, 1.0};
	GLfloat spiegel[] = { 0.296648, 0.296648, 0.296648, 1.0 };
	GLfloat glanz[] = { 100.0 };
	GLfloat lampen_pos0[] = { 0.0, 0.0, 0.0, 1.0 };
	GLfloat lampen_pos1[] = { 1.0, 1.0, 0.0, 1.0 };
	GLfloat Streulicht[] = { 0.2, 0.2, 0.2, 1.0 };
	GLfloat DiffLicht[] = { 0.5, 0.5, 0.5, 1.0 };
	GLfloat weiss[] = { 1.0, 1.0, 1.0, 1.0 };

	glMaterialfv(GL_FRONT, GL_SPECULAR, spiegel);
	glMaterialfv(GL_FRONT, GL_SHININESS, glanz);
	glMaterialfv(GL_FRONT, GL_DIFFUSE, diffus);
	glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);

	glPolygonMode(GL_FRONT, GL_FILL);
	glPolygonMode(GL_BACK, GL_FILL);

	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, Streulicht);
	glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE);
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
	glLightfv(GL_LIGHT0, GL_POSITION, lampen_pos0);
	//glLightfv(GL_LIGHT0, GL_DIFFUSE, weiss);
	glLightfv(GL_LIGHT0, GL_SPECULAR, weiss);
	glLightfv(GL_LIGHT1, GL_POSITION, lampen_pos1);
	glLightfv(GL_LIGHT1, GL_DIFFUSE, weiss);
	glLightfv(GL_LIGHT1, GL_SPECULAR, weiss);

	glEnable(GL_LIGHTING);
	glEnable(GL_LIGHT0);
	//glEnable(GL_DEPTH_TEST);
	glEnable(GL_COLOR_MATERIAL);

	glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, spiegel);

}
